﻿#pragma once

#include <d3d9.h>
#include <d3dx9.h>

#define DELETE_NULL(x) delete x; x=NULL;

#define D3DFVF_VERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)
#define D3DFVF_VERTEX_NORMAL (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_DIFFUSE|D3DFVF_TEX1)

struct State
{
	State(int stateIndex, int stateType,int stateValue)
		:mStateIndex(stateIndex)
		,mStateType(stateType)
		,mStateValue(stateValue)
	{}

	int mStateIndex;
	int mStateType;
	int mStateValue;
};

struct VertexData
{
	float x, y, z;
	DWORD color;
	float tu, tv;
};

struct GeometryData
{
	std::vector<VertexData> mVertexList;
};

struct IndexData
{
	std::vector<int> mIndexList;
};

struct RenderData
{
	RenderData()
		:mVertexSize(0)
		,mVertexCount(0)
		,mVertexBuffer(NULL)
		,mIndexCount(0)
		,mIndexBuffer(NULL)
		,FVF(0)
		,mDrawType(0)
		,mFaceNum(0)
		,mMatrix()
		,mRenderState()
		,mSamplerState()
	{}
	
	int mVertexSize;	//구조체 하나의 사이즈
	int mVertexCount;
	BYTE* mVertexBuffer;
	
	int mIndexCount;
	int* mIndexBuffer;
	
	int FVF;
	int mDrawType;	//Primitive 타입
	int mFaceNum;	//그려질 삼각형의 개수

	D3DXMATRIX mMatrix;
	
	std::vector<State> mRenderState;
	std::vector<State> mSamplerState;
};

typedef std::vector<RenderData*> RenderDataList;

//순수가상클래스 - 순수가상함수가 한개라도 포함되어 있는 클래스를 말한다.
//순수가상클래스는 절대 혼자서 객체화 될 수 없고 상속받아서 순수가상함수를 구현해 줘야 한다.
//RenderListener 曰 : 나를 쓰고 싶으면 내가 아는 함수를 네가 구현해 줘야 하는데
//이름은 알려줄게 VisitRender야. 내용은 니 알아서 하세요. 안그러면 에러 잔뜩 낼테다 뿌잉뿌잉!
class RenderListener
{	
public:
	RenderListener():mRenderDataList(){}
	~RenderListener()
	{
		//for ( ObjectList::iterator it = mObjectList.begin(); it != mObjectList.end(); ++it )
		for (std::vector<RenderData*>::iterator it = mRenderDataList.begin(); it != mRenderDataList.end(); ++it)
		{
			DELETE_NULL(*it);
		}
	}
	virtual void VisitRender(RenderDataList& renderList) = 0;

protected:
	std::vector<RenderData*> mRenderDataList;
};


// vb와 ib의 생성 파괴를 담당하는 객체
template <class T>
struct VertexDataCreator
{
	VertexDataCreator()
		:mVertexData(0)
		,mIndexData(0)
	{
	}

	~VertexDataCreator()
	{
		DELETE_NULL(mVertexData);
		DELETE_NULL(mIndexData);
	}

	T* CreateVB(int count)
	{
		DELETE_NULL(mVertexData);
		mVertexData = new T[count];
		return mVertexData;
	}

	int* CreateIB(int count)
	{
		DELETE_NULL(mIndexData);
		mIndexData = new int[count];
		return mIndexData;
	}

	T* GetVB() const { return mVertexData; }
	int* GetIB() const { return mIndexData; }

	T* mVertexData;
	int* mIndexData;
};
